<?php
//
//	file: includes/attach/class_attach_viewtopic.php
//	author: ptirhiik
//	begin: 01/02/2007
//	version: 1.6.0 - 01/02/2007
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	based on : attachment_mod copyright (c) 2002 Meik Sievertsen (acydburn)
//

if ( !defined('IN_PHPBB') )
{
	die('Hack attempt !');
}

class attach_viewtopic extends plug_ins
{
	function start()
	{
		if ( !(_read('mode', TYPE_NO_HTML) == 'attach') )
		{
			return true;
		}

		// regular phpBB
		global $db, $board_config, $template, $lang, $images, $theme, $phpEx, $phpbb_root_path;
		global $userdata, $user_ip;
		global $orig_word, $replacement_word;
		global $starttime;

		// CH
		global $config, $user, $censored_words, $icons, $navigation, $themes, $smilies, $topics_attr, $requester;
		global $forums, $forum_id;

		// session
		$userdata = session_pagestart($user_ip, PAGE_INDEX);
		$user->set('viewtopic', array('download'));

		$attach_download = new attach_download();
		$attach_download->process();
		unset($attach_download);
		die();
	}
}

class attach_download
{
	var $data;

	function attach_download()
	{
		$this->data = false;
	}

	function process()
	{
		global $db, $user;
		global $config;

		if ( !$this->check_referer() )
		{
			message_die(GENERAL_MESSAGE, 'Not_Authorised');
		}
		if ( isset($config->globals['mod_attachment_CH']['config']->data['disable_mod']) && intval($config->globals['mod_attachment_CH']['config']->data['disable_mod']) )
		{
			message_die(GENERAL_MESSAGE, 'Attachment_feature_disabled');
		}
		if ( !($download_id = _read('id', TYPE_INT)) )
		{
			message_die(GENERAL_ERROR, 'No_attachment_selected');
		}
		if ( !($this->data = $this->read($download_id)) )
		{
			message_die(GENERAL_MESSAGE, 'Error_no_attachment');
		}
		if ( !$this->auth($download_id) )
		{
			message_die(GENERAL_MESSAGE, 'Sorry_auth_view_attach');
		}
		if ( !$this->auth_extension() )
		{
			message_die(GENERAL_MESSAGE, sprintf($user->lang('Extension_disabled_after_posting'), $this->data['extension']));
		}

		// ok, we can send the file
		$this->send();
	}

	function send()
	{
		global $db, $user, $config;

		// Update download count
		if ( !($thumbnail = _read('thumb', TYPE_INT)) )
		{
			$sql = 'UPDATE ' . ATT_DESC_TABLE . '
						SET download_count = download_count + 1
						WHERE attach_id = ' . intval($this->data['attach_id']);
			$db->sql_query($sql, false, __LINE__, __FILE__);
		}
		$filename = ($thumbnail ? THUMB_DIR . '/t_' : '') . basename($this->data['physical_filename']);
		$file_handler = new file_handler($config->globals['mod_attachment_CH']['config']->data);

		// get the appropriate download mode
		$download_mode = isset($this->data['extension']) && isset($config->globals['mod_attachment_CH']['extensions']->data[ $this->data['extension'] ]) ? intval($config->globals['mod_attachment_CH']['extensions']->data[ $this->data['extension'] ]['download_mode']) : INLINE_LINK;
		if ( ($download_mode == PHYSICAL_LINK) && !($dst_file = $file_handler->get_download_url($filename, false)) )
		{
			$download_mode = INLINE_LINK;
		}

		// Physical link asked : redirect to the image url
		if ( $download_mode == PHYSICAL_LINK )
		{
			redirect($dst_file);
		}

		// inline mode : get an internal link to the physical file, if necessary get a temporary file
		$real_filename = html_entity_decode(basename($this->data['real_filename']));
		$tmp_filename = $file_handler->get_temporary($file_handler->path($filename), $this->data['mimetype']);
		if ( !$tmp_filename )
		{
			message_die(GENERAL_ERROR, $file_handler->error());
		}

		// check if ie or opera
		$msie = strpos(' ' . $user->session->get_agent(), 'MSIE');

		// Correct the mime type & set the disposition - we force application/octetstream for all files, except images
		$dispo = 'inline';
		if ( !strpos(' ' . $this->data['mimetype'], 'image') )
		{
			$dispo = 'attachment';
			$this->data['mimetype'] = $msie ? 'application/octetstream' : 'application/octet-stream';
		}

		// headers & file
		header('Pragma: public');
		header('Content-Type: ' . $this->data['mimetype']);
		header('Content-Disposition: ' . $dispo . '; filename="' . rawurlencode($real_filename) . '"');
		if ( ($size = @filesize($tmp_filename)) )
		{
			header('Content-length: ' . intval($size));
		}
		$result = @readfile($tmp_filename);

		// readfile not allowed, try another way
		if ( ($result === false) && ($handler = @fopen($tmp_filename, 'rb')) )
		{
			while ( !feof($handler) )
			{
				echo fread($handler, 8192);
			}
			fclose($handler);
		}

		// delete the temporary file if necessary
		$file_handler->unlink_temporary($tmp_filename);
		unset($file_handler);
	}

	function read($download_id)
	{
		global $db;

		// read the attachment desc
		$sql = 'SELECT *
					FROM ' . ATT_DESC_TABLE . '
					WHERE attach_id = ' . intval($download_id);
		$result = $db->sql_query($sql, false, __LINE__, __FILE__);
		$data = ($row = $db->sql_fetchrow($result)) ? $row : false;
		$db->sql_freeresult($result);
		return $data;
	}

	function auth($download_id)
	{
		global $db, $user, $config;

		// verify the auth to download
		if ( !($authorised = $user->data['user_level'] == ADMIN) )
		{
			// we need only one row (other are copies) : the first will be fine
			$sql = 'SELECT *
						FROM ' . ATT_LINKS_TABLE . '
						WHERE attach_id = ' . intval($this->data['attach_id']) . '
						LIMIT 1';
			$result = $db->sql_query($sql, false, __LINE__, __FILE__);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);
			if ( !$row )
			{
				// here knowing the poster id (so the owner of the file) would be necessary to do a proper check
				$authorised = true;
			}
			else if ( isset($row['post_id']) && intval($row['post_id']) )
			{
				// get the forum
				$sql = 'SELECT forum_id
							FROM ' . POSTS_TABLE . '
							WHERE post_id = ' . intval($row['post_id']);
				$result = $db->sql_query($sql, false, __LINE__, __FILE__);
				$forum_id = ($row = $db->sql_fetchrow($result)) ? intval($row['forum_id']) : 0;
				$db->sql_freeresult($result);
				if ( ($authorised = !empty($forum_id)) )
				{
					if ( !isset($user->cache[POST_FORUM_URL]) || empty($user->cache[POST_FORUM_URL]) )
					{
						$user->get_cache(POST_FORUM_URL);
					}
					$authorised = $user->auth(POST_FORUM_URL, 'auth_download', $forum_id);
				}
			}
			else if ( isset($row['privmsgs_id']) && intval($row['privmsgs_id']) )
			{
				$authorised = false;
				if ( isset($config->globals['mod_attachment_CH']['config']->data['allow_pm_attach']) && intval($config->globals['mod_attachment_CH']['config']->data['allow_pm_attach']) )
				{
					$sql = 'SELECT privmsgs_from_userid, privmsgs_to_userid
								FROM ' . PRIVMSGS_TABLE . '
								WHERE privmsgs_id = ' . intval($row['privmsgs_id']);
					$result = $db->sql_query($sql, false, __LINE__, __FILE__);
					$user_ids = ($row = $db->sql_fetchrow($result)) ? array(intval($row['privmsgs_from_userid']), intval($row['privmsgs_to_userid'])) : array();
					$authorised = in_array($user->data['user_id'], $user_ids);
				}
			}
		}
		return $authorised;
	}

	function auth_extension()
	{
		global $user, $config;

		// Get Information on currently allowed Extensions
		$config->globals['mod_attachment_CH']['extensions']->read();
		return ($user->data['user_level'] != ADMIN) || (isset($this->data['extension']) && isset($config->globals['mod_attachment_CH']['extensions']->data[ $this->data['extension'] ]));
	}

	function check_referer()
	{
		return true; // remove this line if you want to check the referer against allowed/denied sites

		global $config;
		global $HTTP_SERVER_VARS, $HTTP_ENV_VARS;

		// allowed sites
		$allowed_sites = array(
			$config->data['server_name'], // This is your domain
		);

		// denied sites
		$denied_sites = array(
		);

		// get the referer
		$site = isset($HTTP_SERVER_VARS['HTTP_REFERER']) ? trim($HTTP_SERVER_VARS['HTTP_REFERER']) : (isset($HTTP_ENV_VARS) ? trim($HTTP_ENV_VARS['HTTP_REFERER']) : getenv('HTTP_REFERER'));
		$site = explode('?', $site);
		$site = strtolower(trim($site[0]));
		if ( !$site )
		{
			return false;
		}
		$site = ' ' . $site;
		if ( $allowed_sites )
		{
			foreach ( $allowed_sites as $i => $check_site )
			{
				if ( strpos($site, $check_site) )
				{
					return true;
				}
			}
			return false;
		}
		if ( $denied_sites )
		{
			foreach ( $allowed_sites as $i => $check_site )
			{
				if ( strpos($site, $check_site) )
				{
					return false;
				}
			}
		}
		return true;
	}
}

?>